package com.cskaoyan.javase._1extends._10final._3variable._2member;

/**
 * final修饰成员变量表示该成员变量变成了一个常量
 * 它在内存中的位置，生命周期，使用方式等都不会改变。
 * 语法：
 * [访问权限修饰符] final 数据类型 变量名;
 *
 * 成员常量毕竟是一个常量,和成员变量是不同的:
 * 成员常量的赋值不能依赖于默认初始化,必须依赖于new对象过程中,其它三种赋值手段:
 *      1.显式赋值
 *      2.构造器赋值
 *      3.构造代码块赋值
 * 以上三种赋值手段,必须使用其一,也只能使用其一.
 * 注意,如果使用构造器给某个成员常量赋值,必须保证每一个构造器都能完成它的赋值.
 *
 * 思考:
 *      所谓的成员常量,算不算一个真正意义上的常量?
 *      不能算,因为虽然创建对象完毕后,该成员常量不可改变,但是在new对象时,如果用构造器赋值,那么不同对象的成员常量取值完全可以不同,这并不是真正意义上的常量
 *      那么如果需要定义一个真正意义上的常量,怎么办呢?
 *      final修饰的静态成员变量,在类的全局唯一,且取值常量不变,它是一个真正意义上的常量
 *      在开发中是最常用的自定义常量,也是final最常使用的场景.
 *
 *
 * @since 10:04
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        System.out.println(s.age);
        System.out.println(s.name);
        System.out.println(s.score);
        // s.age = 19;
        // s.score = 75;

        Student s2 = new Student(800);
        System.out.println(s2.score);
    }
}

class Student {
    // Variable 'age' might not have been initialized
    final int age = 18;
    final String name;
    final double score;

    {
        // age = 20;
        name = "张三";
    }

    public Student(double score) {
        this.score = score;
    }

    public Student() {
        score = 750;
    }
}